#!/usr/bin/perl -w
# Bug reports and comments to Igor.Ermolaev@intel.com
use strict;
no warnings 'portable';

use constant { FALSE=>0, TRUE=>-1 };

use constant
{
   SRC_LINE=>qr/^\s*[^:]+\:\d+\s*$/o,
   ASM_LINE=>qr/^\s*([[:xdigit:]]+)\:\s*([[:xdigit:]][[:xdigit:]]\s+)*\s*(.+)$/o,
};

my $instrs_bfr = undef;
my $instrs_aft = undef;
my $body_rqrd  = FALSE;

my $i;
for( $i = 0; $i <= $#ARGV; $i++ )
{
   $_ = $ARGV[$i];
   if( /^\d+$/o )
   {
      if( defined $instrs_bfr ){ $instrs_aft = int $_; }
      else                     { $instrs_bfr = int $_; }
   }
   elsif( $_ eq '-b' )
   {
      $body_rqrd = TRUE;
   }
   else{ last; }
}

my @cache    = ();
my $lst_srcl = undef;
my $rest     = undef;
my $sep_idx  = 0;

while( <STDIN> )
{
   next if /^;\s/o;
   if( $_ =~ SRC_LINE )
   {
      if( defined $lst_srcl )
      {
         next if $lst_srcl eq $_;
         pop @cache if $cache[-1] =~ SRC_LINE;
      }
      $lst_srcl = $_;
   }
   elsif( $_ =~ /^;---/o )
   {
      $sep_idx++;
      if( $sep_idx == 1 )
      {
         my $mrgn    = $instrs_bfr;
         my $fst_idx = $mrgn > 0 ? undef : $#cache+1;
         my $srcl    = undef;
         my $from;
         for( $from = $#cache; $from >= 0; $from-- )
         {
            if( $cache[$from] =~ SRC_LINE && defined $fst_idx )
            {
               $srcl = $cache[$from];
               last;
            }
            elsif( !defined $fst_idx && $cache[$from] =~ ASM_LINE )
            {
               $mrgn--;
               $fst_idx = $from if $mrgn == 0;
            }
         }
         splice  @cache, 0, $fst_idx;
         unshift @cache, $srcl if defined $srcl;
      }
      elsif( $sep_idx == 2 )
      {
         $rest = $instrs_aft;
      }
   }
   next if /^;---/o;
   push @cache, $_ if $_ =~ SRC_LINE || ( !defined $rest || $rest > 0 ) && ( $sep_idx != 1 || $body_rqrd == TRUE);
   if( defined $rest )
   {
      $rest-- if $rest > 0 && $_ =~ ASM_LINE;
      if( $rest == 0 )
      {
         print @cache;
         $rest = undef;
      }
   }
}

exit 0;
